/**
 * Created by 功振 on 2016/3/31.
 */
module.controller('ConfigFileSetCreateController',
    function ($scope, $state, $stateParams, $cookies,$timeout,$http, k8sService, dockerRegisterService,
              storageService,utilService,AppConfigService) {
    //$scope.version=null;
    $scope.svcnameReg = '[a-z0-9]([-a-z0-9]*[a-z0-9])?';
      $scope.mountTargetPathReg=/^([/]([\w])*)*$/;
      $scope.ports = [];
    //$scope.volumes = [];
    //for service update
    $scope.curTag = undefined;
        $scope.focus =false;
    //this from image
    $scope.volumePoints = [];
    $scope.cfgSet = [];

    $scope.serviceOperation = "创建";
    var user = $cookies.get("username");
    var existVersionList = [];


    //$scope.sub.version = "";

    //default create volume by system
    $scope.curVolume = {};
    $scope.curEnv = {};
    $scope.curEnvInfo = [{}];
    $scope.lock = false;
    $scope.uptPrevItem = undefined;


    if($scope.op === 'update'){
        loadTagsInfo();
    }
    //load exist tag
    else{
        loadExistTag();
    }


    function addPortInfo(portInfo) {
        $scope.sub.portInfos.push(portInfo);
    }

    function _initCurEnvInfo(envInfo){
            envInfo.name = undefined;
            envInfo.value = undefined;
        }

    $scope.deletePortInfo = function(index) {
        $scope.sub.portInfos.splice(index, 1);
    }

    $scope.addEnv = function(envInfo,index) {
        if (isEmpty(envInfo.name) || isEmpty(envInfo.value)) {
            alertify.alert("环境变量的名称和值都不能为空");
            return;
        }
        var _item = utilService.deepCopyObj(envInfo);
        $scope.sub.envInfos[index].info = $scope.sub.envInfos[index].info || [];
        $scope.sub.envInfos[index].info.push(_item);
        _initCurEnvInfo(envInfo);
    };
    $scope.newEnv=function () {
        if($scope.curEnv !== undefined  && $scope.curEnv.name !== "" && $scope.curEnv.name !== undefined){
            var _item = utilService.deepCopyObj($scope.curEnv);
            $scope.sub.envInfos.push(_item);
            $scope.curEnv = {};
        }
    }
    $scope.removeSet=function(index){
        $scope.sub.envInfos.splice(index, 1);
    }
    $scope.deleteEnv = function(index,i) {
        $scope.sub.envInfos[$scope.activeSelected].info.splice(index,1);
    }

    $scope.addFile=function() {
        var filepath = $scope.sub.filepath;
        if(filepath==null||filepath.trim()==""){
            return;
        }
        var file={
            filepath:filepath
        }
        $scope.files.push(file);
        updateEditorHeight();
        $scope.editFile(file);
    }


    $scope.addClassActive=function (index,env) {
      var Top=jQuery("#configCreateGroup dd.linePosition").eq(index).position().top;
        jQuery(".configLine").css('top',parseInt(Top)-2+"px");
      $scope.envData=env;
        $scope.activeSelected=index;
    }

    $scope.changeNodePort = function(portInfo) {
        if (portInfo.isPublic && portInfo.accessProtocol === 'TCP') {
            portInfo.nodePortPlcaeHolder = "动态生成";
        } else
            portInfo.nodePortPlcaeHolder = "";
    }
    $scope.changePodAutoScale = function (autoScalerEnabledTarget) {
            $scope.autoScalerEnabledTarget = autoScalerEnabledTarget;
        }

    $scope.delEnv = function(index){
        $scope.sub.envInfos[$scope.activeSelected].info.splice(index,1);
    }

    function isEmpty(value) {
        return !value || value == "";
    }

    var updateEditorHeight=function () {
        if(jQuery("div.filelist").clientHeight>jQuery("div.editarea").clientHeight){

        }
    }

    $scope.$on('submit',function() {

        if($scope.files === undefined){
            alertify.error('not found files');
            return;
        }

        var env=JSON.parse(JSON.stringify($scope.sub.envInfos));
        var envs={};
        for(var index in env){
            var obj={};
            //把数组转为k->v形式
            if(env[index].info !== undefined ){
                for(var i in env[index].info){
                    obj[env[index].info[i].name]=env[index].info[i].value;
                }
                envs[env[index].name]=obj;
            }

        }
        //console.log(envs);

        var files=JSON.parse(JSON.stringify($scope.files));
        var filesToAdd=[];
        for(var index=0 ; index < files.length; index++){
            if(files[index].version==undefined||files[index].originValue!=files[index].value) {
                filesToAdd.push(files[index]);
                files.splice(index,1);
                --index;
            }
        }
        //files = [];
        //console.log(files);
        //console.log(filesToAdd);

        var querys=[];
        for(var index in filesToAdd){
            querys.push(new Promise(function(resolve,reject){
                $http({
                    url:'/appConfig/addConfigFile',
                    method:'POST',
                    data:{
                        imageName:$scope.curImg.name,
                        filepath:filesToAdd[index].filepath,
                        value:filesToAdd[index].value
                    }
                }).success(function(data,header,config,status){
                    if(data!="false"){
                        resolve(data);
                    }else
                        reject();
                }).error(function(data,header,config,status){
                    reject();
                });
            }));
        }
        Promise.all(querys).then(function (vals) {
            files=files.concat(vals);
            var filesToStore=[];
            for(var index in files){
                filesToStore.push({
                    filepath:files[index].filepath,
                    version:files[index].version
                });
            }
            var _url = '/appConfig/upsertConfigFileSet';
            var _data = {
                imageVersion:$scope.sub.version || $scope.sub.SelectedTag ,
                imageName:$scope.curImg.name,
                isMarket:$scope.curImg.isMarket,
                files:filesToStore,
                envs:envs
            };

            if($scope.op === 'update'){
                delete _data.envs;
                _url = '/appConfig/udpConfigFileSet';
            }

            return new Promise(function (resolve, reject) {
                $http({
                    url:_url,
                    method:'POST',
                    data:_data
                }).success(function(data,header,config,status){
                    if(data!="false"){
                        resolve(data);
                    }else
                        reject();
                }).error(function(data,header,config,status){
                    reject();
                });
            })
        }).then(function (val) {
            alertify.success("添加成功！");
            $state.go("cp.configFileSetList");
        })
    });

    $scope.$watch('sub.SelectedTag',function(newValue, oldValue){
        if(newValue != undefined && $scope.imagesData !== undefined && $scope.imagesData.meta !== undefined){
            //exclude first time when service update
            if($scope.op !== 'update' || oldValue !== undefined){



            }
        }
    });



    /*
    *
    *  local function part
    *
    * */

    function loadTagsInfo(){

        var envs=$scope.cfs.envs;
        if(envs==undefined||envs=={}){
            $scope.sub.envInfos = [{}];
        }else{
            $scope.sub.envInfos = [{}];
            for(var name in envs){
                var obj={
                    name:name,
                    value:[]
                }
                for(var key in envs[name]){
                    obj.value.push({name:key,value:envs[name][key]})
                }
                $scope.sub.envInfos.push(obj);
            }
        }

        //image
        $scope.sub.versionList = $scope.cfs.verList;
        if($scope.cfs.verItem){
            $scope.sub.version=$scope.cfs.verItem.imgVersion;

            $scope.imagesTags=[$scope.cfs.verItem.imgVersion];
            $scope.curTag = $scope.cfs.verItem.imgVersion;
        }else{

            //为了适应接口
            var _ns = "library";
            if($scope.cfs.isMarket === false)
                _ns = user;
            var _imgUrl = "naturecloud.io/"+_ns+"/"+$scope.cfs.imageName+":";
            dockerRegisterService.getTagFromRegistry(_imgUrl).then(function(rets){
                //$scope.imagesTags = rets.data.slice();
                $scope.imagesTags = [];
                var _ver_item_list = [];
                $scope.sub.versionList.forEach(function(ver_item){
                    _ver_item_list.push(ver_item.imgVersion);
                });
                rets.data.forEach(function(version){
                    if(_ver_item_list.indexOf(version) === -1)
                        $scope.imagesTags.push(version);
                })
            });
        }

        $scope.imagesData={
            shortname:$scope.cfs.imageName
        }

    }

    function loadExistTag(){

        //add version
        if($scope.cfgSet.length !== 0){
            $scope.cfgSet.forEach(function(item){
                if(item._id === $scope.curImg.name){
                    item.versionList.forEach(function(version_item){
                        existVersionList.push(version_item.imgVersion);
                    })
                    $scope.sub.versionList = item.versionList;
                }
            });
        }
        //create from create button
        else if($scope.FromVersion !== undefined){
            $scope.FromVersion.versionList.forEach(function(version_item){
                existVersionList.push(version_item.imgVersion);
            })
            $scope.sub.versionList = $scope.FromVersion.versionList;
        }



    }

    $scope.$watch('curImg', function(newValue, oldValue) {
            if(newValue != undefined){
                console.log('change to '+newValue.name);
                dockerRegisterService.getImageInfo(newValue).then(function(rets){
                    if($scope.op!='update') {
                        $scope.imagesData = rets.data.results[0];
                        $scope.imagesData.isMarket = newValue.isMarket;
                        $scope.imagesTags = []
                        $scope.imagesData.taglist.forEach(function(tag){
                            if(existVersionList.indexOf(tag) === -1)
                                $scope.imagesTags.push(tag);
                        });

                        //if operator is create, set latest tag
                        if ($scope.op === 'create')
                            $scope.sub.SelectedTag = $scope.imagesTags[0];
                        else if ($scope.op === 'update') {
                            $scope.sub.SelectedTag = $scope.curTag;
                            //get udp item data
                            if ($scope.uptPrevItem === undefined)
                                $scope.uptPrevItem = getItem();
                        }


                        var meta = $scope.imagesData.meta;
                        if (meta && meta.attention) {
                            $scope.hasAttention = true;
                            $scope.attention = meta.attention;
                        }

                    }else{
                        $scope.sub.SelectedTag = $scope.curTag;
                    }
                },function(){

                });

            }
        });

    /**
     * a json format requestBody,there is a data sample file :
     *  /new-docker/sample/sampleData.json
     */
    function getItem(){
            var ret = {
                app:$scope.sub.ServiceName,
                rcnum:parseInt($scope.sub.RequestrePlicas),
                //maybe the version should put inside node, and this version is rc version
                ver:$scope.sub.SelectedTag
            }

            //var img = $scope.sub.SelectedImage.imgPath +':'+ $scope.sub.SelectedImage.imageversion;
            var img = $scope.imagesData.imgPath +':'+ $scope.sub.SelectedTag;

            //init node struct
            ret.node = {
                "image" : img,
                "imageshortname":$scope.imagesData.shortname,
                "isMarket":$scope.imagesData.isMarket,
                "ports" : [ ] ,
                "env":[],

                "clusterId":$scope.sub.curCluster.clusterId,
                "synctimezone":$scope.sub.SyncTimeZone
            };

            //spec only support by public cloud
            if( $scope.sub.curCluster.clusterId === 'default'){
                ret.node["cpu_shares"]= $scope.sub.Request.split(' ')[0].replace('Core','');
                ret.node["mem_limit"] =$scope.sub.Request.split(' ')[1].replace('M', 'Mi');
            }

            if (!isEmpty($scope.sub.command))
                ret.node.commands = $scope.sub.command;

            //set service command
            if($scope.imagesData.meta !== undefined){
                if (isEmpty(ret.node.commands)) {
                    var _cmd = $scope.imagesData.meta.commands;
                    if ($scope.imagesData.meta[$scope.sub.SelectedTag] !== undefined && $scope.imagesData.meta[$scope.sub.SelectedTag].commands !== undefined)
                        _cmd = $scope.imagesData.meta[$scope.sub.SelectedTag].commands;

                    if (_cmd !== undefined)
                        ret.node.commands = _cmd.slice();
                }

                var shell = $scope.imagesData.meta.shell;
                if (shell)
                    ret.node.shell = shell;
            }

            var portInfos = $scope.sub.portInfos;
            portInfos.forEach(function(portInfo) {
                var port = {
                    isPublic: portInfo.isPublic,
                    port:parseInt(portInfo.targetPort),
                    targetPort: parseInt(portInfo.targetPort),
                    protocol:"TCP",
                    accessProtocol:portInfo.accessProtocol
                };
                //if(ret.node.clusterId !== 'default'){
                    if (!isEmpty(portInfo.nodePort))
                        port.nodePort = parseInt(portInfo.nodePort);
                //}
                ret.node.ports.push(port);
            });

            var envInfos = $scope.sub.envInfos;
            envInfos.forEach(function(envInfo){
                ret.node.env.push({name:envInfo.name, value: envInfo.value});
            });

            //set volumes
            ret.node.volumes = [];
            var _mapVolParent = {};
            $scope.sub.volumes.forEach(function(item){
                //use default volume create by system when volume type is glusterfs
                if(item.IsDefault && !isHostPath() ){
                    console.log("clear the moutObj...") ;
                    //item.mountObj = undefined;
                }
                if(item.IsDefault !== undefined || _mapVolParent[item.mountName] !== undefined ){
                    _mapVolParent[item.mountName] = _mapVolParent[item.mountName] || true;
                    ret.node.volumes.push(utilService.deepCopyObj(item));
                }

            });

            return ret;
        }

    function isObjectValueEqual(a, b) {
        // Of course, we can do it use for in
        // Create arrays of property names
        var aProps = Object.getOwnPropertyNames(a);
        var bProps = Object.getOwnPropertyNames(b);

        // If number of properties is different,
        // objects are not equivalent
        if (aProps.length != bProps.length) {
            return false;
        }

        for (var i = 0; i < aProps.length; i++) {
            var propName = aProps[i];

            // If values of same property are not equal,
            // objects are not equivalent
            if(a[propName] instanceof  Array && b[propName] instanceof  Array){
                if(isArrayValueEqual(a[propName],b[propName]) === false)
                    return false;
            }
            else if (a[propName] instanceof  Object && b[propName] instanceof  Object) {
                if(isObjectValueEqual(a[propName],b[propName]) === false)
                    return false;
            }
            else if(a[propName] !== b[propName])
                return false;
        }

        // If we made it this far, objects
        // are considered equivalent
        return true;
    }

    function isArrayValueEqual(a, b) {
        if (a.length != b.length) {
            return false;
        }

        for (var i = 0; i < a.length; i++) {
            if(a[i] instanceof  Array && b[i] instanceof  Array){
                if(isArrayValueEqual(a[i],b[i]) === false)
                    return false;
            }
            else if (a[i] instanceof  Object && b[i] instanceof  Object) {
                if(isObjectValueEqual(a[i],b[i]) === false)
                    return false;
            }
            else if(a[i] !== b[i])
                return false;
        }

        return true;
    }





});
